home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / util / misc / UserTool1_0.lha / UserTool / Source / stubs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-22  |  16.3 KB  |  594 lines

  1. /*
  2.  * UserTool - A Tool for managing users in a MuFS environment.
  3.  *
  4.  * $VER: stubs.c 37.1 (10.1.94)
  5.  */
  6.  
  7. #include <exec/memory.h>
  8. #include <exec/execbase.h>
  9. #include <intuition/intuition.h>
  10. #include <dos/dos.h>
  11. #include <workbench/workbench.h>
  12.  
  13. #include <libraries/gadtools.h>
  14. #include <libraries/reqtools.h>
  15.  
  16. #include <clib/exec_protos.h>
  17. #include <clib/intuition_protos.h>
  18. #include <clib/gadtools_protos.h>
  19. #include <clib/reqtools_protos.h>
  20. #include <clib/dos_protos.h>
  21. #include <clib/icon_protos.h>
  22. #include <clib/alib_protos.h>
  23.  
  24. #include <proto/multiuser.h>
  25.  
  26. #include <string.h>
  27.  
  28. #include "UserTool_rev.h"
  29. #include "UserTool.h"
  30. #include "parse.h"
  31. #include "funcs.h"
  32.  
  33. extern struct ExecBase *ExecBase;
  34. extern struct List *Users, *Groups;
  35. extern UserStruct *CurUser;
  36. extern GroupStruct *CurGroup;
  37. extern LONG Tags[], PasswdFileDirty, GroupFileDirty;
  38.  
  39. UBYTE *Ptr;
  40.  
  41. int HOMEDIRClicked( void )
  42. {
  43.     BPTR HomeDirLock;
  44.  
  45.     if( ExecBase->LibNode.lib_Version < 39 )
  46.         Ptr = (( struct StringInfo * )
  47.                UserToolGadgets[GD_HOMEDIR]->SpecialInfo )->Buffer;
  48.     else
  49.         GT_GetGadgetAttrs( UserToolGadgets[GD_HOMEDIR], UserToolWnd, 0L,
  50.                           GTST_String, &Ptr, TAG_END );
  51.     
  52.     if( strcmp( CurUser->us_HomeDir, Ptr )) {
  53.         strcpy( CurUser->us_HomeDir, Ptr );
  54.         PasswdFileDirty = 1;
  55.         HomeDirLock = Lock( CurUser->us_HomeDir, ACCESS_READ );
  56.         if( !HomeDirLock ) {
  57.             Tags[7] = ( LONG )"Home Directory Information";
  58.             switch( rtEZRequest( "That directory does not exist, would you"
  59.                                 " like to have it created?",
  60.                                 "_Yes|Yes, with _Icon|_No", 0L,
  61.                                 ( struct TagItem * )Tags )) {
  62.             case 0:
  63.                 break;    
  64.             case 2: {
  65.                 struct DiskObject *HomeDirIcon;
  66.                 
  67.                 if( HomeDirIcon = GetDefDiskObject( WBDRAWER )) {
  68.                     if( !PutDiskObject( CurUser->us_HomeDir, HomeDirIcon ))
  69.                         rtEZRequest( "An error occured when trying to write"
  70.                                     " the icon for the directory.", "_Ok", 0L,
  71.                                     ( struct TagItem * )Tags );
  72.                     FreeDiskObject( HomeDirIcon );
  73.                 } else    
  74.                     rtEZRequest( "An error occured when trying to get the"
  75.                                 " default drawer icon.", "_Ok", 0L,
  76.                                 ( struct TagItem * )Tags );
  77.             }
  78.             case 1:
  79.                 if( HomeDirLock = CreateDir( CurUser->us_HomeDir )) {
  80.                     UnLock( HomeDirLock );
  81.                     rtEZRequest( "Directory successfully created.", "_Ok", 0L,
  82.                                 ( struct TagItem * )Tags );
  83.                 } else
  84.                     rtEZRequest( "An error occured when trying to create the"
  85.                                 " directory.", "_Ok", 0L,
  86.                                 ( struct TagItem * )Tags );
  87.                 break;
  88.             default:
  89.                 break;
  90.             }
  91.         } else
  92.             UnLock( HomeDirLock );
  93.     }
  94.  
  95.     return 1;
  96. }
  97.  
  98. int REALNAMEClicked( void )
  99. {
  100.     if( ExecBase->LibNode.lib_Version < 39 )
  101.         Ptr = (( struct StringInfo * )
  102.                UserToolGadgets[GD_REALNAME]->SpecialInfo )->Buffer;
  103.     else
  104.         GT_GetGadgetAttrs( UserToolGadgets[GD_REALNAME], UserToolWnd, 0L,
  105.                           GTST_String, &Ptr, TAG_END );
  106.     if( strcmp( CurUser->us_RealName, Ptr )) {
  107.         strcpy( CurUser->us_RealName, Ptr );
  108.         PasswdFileDirty = 1;
  109.     }
  110.     
  111.     return 1;
  112. }
  113.  
  114. int USERIDClicked( void )
  115. {
  116.     LONG OldID = CurUser->us_UserID;
  117.     
  118.     if( ExecBase->LibNode.lib_Version < 39 )
  119.         CurUser->us_UserID = (( struct StringInfo * )
  120.                               UserToolGadgets[GD_USERID]->SpecialInfo
  121.                               )->LongInt;
  122.     else
  123.         GT_GetGadgetAttrs( UserToolGadgets[GD_USERID], UserToolWnd, 0L,
  124.                           GTIN_Number, &CurUser->us_UserID, TAG_END );
  125.     
  126.     if( !UniqueID( CurUser )) {
  127.         Tags[7] = ( LONG )"UserID Information";
  128.         rtEZRequest( "User ID number is already in use, please enter another.",
  129.                     "_Ok", 0L, ( struct TagItem * )Tags );
  130.         ActivateGadget( UserToolGadgets[GD_USERID], UserToolWnd, 0L );
  131.     }
  132.     
  133.     if( CurUser->us_UserID != OldID )
  134.         PasswdFileDirty = 1;
  135.     
  136.     return 1;
  137. }
  138.  
  139. int PORTClicked( void )
  140. {
  141.     if( ExecBase->LibNode.lib_Version < 39 )
  142.         Ptr = (( struct StringInfo * )
  143.                UserToolGadgets[GD_PORT]->SpecialInfo )->Buffer;
  144.     else
  145.         GT_GetGadgetAttrs( UserToolGadgets[GD_PORT], UserToolWnd, 0L,
  146.                       GTST_String, &Ptr, TAG_END );
  147.     if( strcmp( CurUser->us_Port, Ptr )) {
  148.         strcpy( CurUser->us_Port, Ptr );
  149.         PasswdFileDirty = 1;
  150.     }
  151.  
  152.     return 1;
  153. }
  154.  
  155. int USERSSTRClicked( void )
  156. {
  157.     if( ExecBase->LibNode.lib_Version < 39 )
  158.         Ptr = (( struct StringInfo * )
  159.                UserToolGadgets[GD_USERSSTR]->SpecialInfo )->Buffer;
  160.     else
  161.         GT_GetGadgetAttrs( UserToolGadgets[GD_USERSSTR], UserToolWnd, 0L,
  162.                           GTST_String, &Ptr, TAG_END );
  163.     if( strcmp( CurUser->us_UserName, Ptr )) {
  164.         GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  165.                           GTLV_Labels, ~0, TAG_DONE );
  166.         strcpy( CurUser->us_UserName, Ptr );
  167.         GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  168.                           GTLV_Labels, Users, TAG_DONE );
  169.         PasswdFileDirty = 1;
  170.     }
  171.     
  172.     return 1;
  173. }
  174.  
  175. int USERSClicked( void )
  176. {
  177.     UpdateGadgets( UserToolMsg.Code );
  178.     
  179.     return 1;
  180. }
  181.  
  182. int CHANGEPASSClicked( void )
  183. {
  184.     LONG CPTags[] = { RT_Window, 0L, RT_LockWindow, TRUE, RTGS_Invisible,
  185.                         TRUE, RTGS_TextFmt, 0L, RTGS_Flags, GSREQF_CENTERTEXT,
  186.                         TAG_END };
  187.     UBYTE *PassBuf;
  188.     LONG ListPos;
  189.     
  190.     if( PasswdFileDirty ) {
  191.         Tags[7] = ( LONG )"Password File Information";
  192.         if( rtEZRequest( "All changes to the password file must\n"
  193.                         "be flushed before a password can be changed.\n"
  194.                         "Shall I save the changes now?", "_Ok|_Cancel", 0L,
  195.                         ( struct TagItem * )Tags )) {
  196.             WritePasswdFile( 0L );
  197.             PasswdFileDirty = 0;
  198.         } else
  199.             return 1;
  200.     }
  201.         
  202.     if( PassBuf = AllocVec( sizeof( UBYTE ) * 64, MEMF_CLEAR )) {
  203.         CPTags[1] = ( LONG )UserToolWnd;
  204.         CPTags[7] = ( LONG )"Please enter the new password.";
  205.         
  206.         if( rtGetStringA( PassBuf, 64, "Changing Password", 0L,
  207.                          ( struct TagItem * )CPTags )) {
  208.             LONG LoginTags[] = { muT_Task, 0L, muT_UserID, 0L, muT_Password,
  209.                                      ( LONG )"", TAG_END };
  210.             LoginTags[1] = ( LONG )FindTask( 0L );
  211.             LoginTags[3] = ( LONG )CurUser->us_UserName;
  212.             WritePasswdFile( CurUser );
  213.             if( muLoginA(( struct TagItem * )LoginTags )) {
  214.                 LONG LogoutTags[] = { muT_Quiet, TRUE, TAG_END };
  215.                 Tags[7] = ( LONG )"Password Information";
  216.                 if( muPasswd( "", PassBuf ))
  217.                     rtEZRequest( "Password succesfully changed.", "_Ok",
  218.                                 0L, ( struct TagItem * )Tags );
  219.                 else
  220.                     rtEZRequest( "Password change failed.", "_Ok",
  221.                                 0L, ( struct TagItem * )Tags );
  222.                 muLogoutA(( struct TagItem * )LogoutTags );
  223.             }
  224.         }
  225.         FreeVec( PassBuf );
  226.     }
  227.  
  228.     return 1;
  229. }
  230.  
  231. int NEWClicked( void )
  232. {
  233.     UserStruct *NewUser;
  234.     LONG ListPos;
  235.     
  236.     if( NewUser = AllocVec( sizeof( UserStruct ), MEMF_CLEAR )) {
  237.         GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  238.                           GTLV_Labels, ~0, TAG_DONE );
  239.         NewUser->us_UserID = GetNextUID();
  240.         strcpy( NewUser->us_UserName, "(new)" );
  241.         strcpy( NewUser->us_Port, "cli" );
  242.         GetVar( "DEFHOMEDIR", NewUser->us_HomeDir, muHOMEDIRSIZE, 0L );
  243.         NewUser->us_Node.ln_Name = NewUser->us_UserName;
  244.         NewList( &NewUser->us_Groups );
  245.         Insert( Users, ( struct Node * )NewUser, ( struct Node * )CurUser );
  246.         GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  247.                           GTLV_Labels, Users, TAG_DONE );
  248.         CurUser = NewUser;
  249.         ListPos = NodePos( Users, ( struct Node * )CurUser );
  250.         GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  251.                           GTLV_Selected, ListPos, TAG_DONE );
  252.         UpdateGadgets( ListPos );
  253.         ActivateGadget( UserToolGadgets[GD_USERSSTR], UserToolWnd, 0L );
  254.         PasswdFileDirty = 1;
  255.     }
  256.  
  257.     return 1;
  258. }
  259.  
  260. int DELETEClicked( void )
  261. {
  262.     UserStruct *OldUser = CurUser;
  263.  
  264.     if( CurUser->us_UserID == 65535 ) {
  265.         Tags[7] = ( LONG )"Access Information";
  266.         rtEZRequest( "That user is root. You cannot delete root.", "_Ok", 0L,
  267.                     ( struct TagItem * )Tags );
  268.         return 1;
  269.     }
  270.  
  271.     if( CurUser->us_Node.ln_Succ != ( struct Node * )&( Users->lh_Tail ))
  272.         CurUser = ( UserStruct * )CurUser->us_Node.ln_Succ;
  273.     else if( CurUser->us_Node.ln_Pred != ( struct Node * )Users )
  274.         CurUser = ( UserStruct * )CurUser->us_Node.ln_Pred;
  275.     else {
  276.         Tags[7] = ( LONG )"Password File Information";
  277.         rtEZRequest( "You must have at least one user the password file.",
  278.                     "_Ok", 0L, ( struct TagItem * )Tags );
  279.         return 1;
  280.     }
  281.     
  282.     GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  283.                       GTLV_Labels, ~0, TAG_DONE );
  284.     Remove(( struct Node * )OldUser );
  285.     FreeVec( OldUser );
  286.     GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  287.                       GTLV_Selected, UserToolMsg.Code, TAG_DONE );
  288.     GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  289.                       GTLV_Labels, Users, TAG_DONE );
  290.     UpdateGadgets( NodePos( Users, ( struct Node * )CurUser ));
  291.     
  292.     return PasswdFileDirty = 1;
  293. }
  294.  
  295. int GROUPSTRClicked( void )
  296. {
  297.     if( ExecBase->LibNode.lib_Version < 39 )
  298.         Ptr = (( struct StringInfo * )
  299.                UserToolGadgets[GD_GROUPSTR]->SpecialInfo )->Buffer;
  300.     else
  301.         GT_GetGadgetAttrs( UserToolGadgets[GD_GROUPSTR], UserToolWnd, 0L,
  302.                           GTST_String, &Ptr, TAG_END );
  303.     if( strcmp( CurGroup->gs_GroupID, Ptr )) {
  304.         GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  305.                           GTLV_Labels, ~0, TAG_DONE );
  306.         strcpy( CurGroup->gs_GroupID, Ptr );
  307.         GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  308.                           GTLV_Labels, Groups, TAG_DONE );
  309.         GroupFileDirty = 1;
  310.     }
  311.     
  312.     return 1;
  313. }
  314.  
  315. int GROUPSClicked( void )
  316. {
  317.     UpdateGroups( UserToolMsg.Code );
  318.     
  319.     return 1;
  320. }
  321.  
  322. int NEWGROUPClicked( void )
  323. {
  324.     GroupStruct *NewGroup;
  325.     ULONG ListPos, GID;
  326.     LONG NMTags[] = { RT_Window, 0L, RT_LockWindow, TRUE, RTGS_TextFmt, 0L,
  327.                            RTGS_Flags, GSREQF_CENTERTEXT, TAG_END };
  328.     LONG IDTags[] = { RT_Window, 0L, RT_LockWindow, TRUE, RTGL_TextFmt, 0L,
  329.                           RTGL_ShowDefault, TRUE, TAG_END };
  330.     UBYTE NameBuf[muGROUPNAMESIZE];
  331.  
  332.     NameBuf[0] = '\0';
  333.     NMTags[1] = IDTags[1] = ( LONG )UserToolWnd;
  334.     NMTags[5] = ( LONG )"Please enter the name for this new group.";
  335.     if(!( rtGetStringA( NameBuf, 64, "New Group Name", 0L,
  336.                        ( struct TagItem * )NMTags )))
  337.         return 1;
  338.  
  339.     GID = GetNextGID();
  340.     IDTags[5] = ( LONG )"Please enter the ID for this new group.";
  341.     if(!( rtGetLongA( &GID, "New Group ID", 0L, ( struct TagItem * )IDTags )))
  342.         return 1;
  343.     
  344.     if( NewGroup = AllocVec( sizeof( GroupStruct ), MEMF_CLEAR )) {
  345.         GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  346.                           GTLV_Labels, ~0, TAG_DONE );
  347.         strcpy( NewGroup->gs_GroupID, "(new)" );
  348.         NewGroup->gs_GID = GID;
  349.         NewGroup->gs_MgrID = CurUser->us_UserID;
  350.         strcpy( NewGroup->gs_Name, NameBuf );
  351.         NewGroup->gs_Node.ln_Name = NewGroup->gs_GroupID;
  352.         Insert( Groups, ( struct Node * )NewGroup, ( struct Node * )CurGroup );
  353.         GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  354.                           GTLV_Labels, Groups, TAG_DONE );
  355.         CurGroup = NewGroup;
  356.         ListPos = NodePos( Groups, ( struct Node * )CurGroup );
  357.         GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  358.                           GTLV_Selected, ListPos, TAG_DONE );
  359.         UpdateMember();
  360.         ActivateGadget( UserToolGadgets[GD_GROUPSTR], UserToolWnd, 0L );
  361.         GroupFileDirty = 1;
  362.     }
  363.  
  364.     return 1;
  365. }
  366.  
  367. int DELETEGROUPClicked( void )
  368. {
  369.     GroupStruct *OldGroup = CurGroup;
  370.     UserStruct *TmpUser;
  371.     
  372.     if( CurGroup->gs_Node.ln_Succ != ( struct Node * )&( Groups->lh_Tail ))
  373.         CurGroup = ( GroupStruct * )CurGroup->gs_Node.ln_Succ;
  374.     else if( CurGroup->gs_Node.ln_Pred != ( struct Node * )Groups )
  375.         CurGroup = ( GroupStruct * )CurGroup->gs_Node.ln_Pred;
  376.     else {
  377.         Tags[7] = ( LONG )"Group File Information";
  378.         rtEZRequest( "You must have at least one group the group file.",
  379.                     "_Ok", 0L, ( struct TagItem * )Tags );
  380.         return 1;
  381.     }
  382.     
  383.     GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  384.                       GTLV_Labels, ~0, TAG_DONE );
  385.     for( TmpUser = ( UserStruct * )Users->lh_Head; TmpUser->us_Node.ln_Succ;
  386.         TmpUser = ( UserStruct * )TmpUser->us_Node.ln_Succ )
  387.         RemoveGroupFromUser( TmpUser->us_UserID, OldGroup->gs_GID );
  388.     Remove(( struct Node * )OldGroup );
  389.     FreeVec( OldGroup );
  390.     GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  391.                       GTLV_Selected, UserToolMsg.Code, TAG_DONE );
  392.     GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  393.                       GTLV_Labels, Groups, TAG_DONE );
  394.     UpdateMember();
  395.     
  396.     return GroupFileDirty = 1;
  397. }
  398.  
  399. void DoMEMBER( LONG Selection )
  400. {
  401.     UserStruct *User;
  402.  
  403.     if( CurUser->us_UserID == CurGroup->gs_MgrID ) {
  404.         Tags[7] = ( LONG )"Group File Information";
  405.         rtEZRequest( "You cannot remove the manager of a group.\nYou must"
  406.                     " select the new manager and the old one will\n"
  407.                     " automatically be removed from the status of manager.",
  408.                     "_Ok", 0L, ( struct TagItem * )Tags );
  409.         GT_SetGadgetAttrs( UserToolGadgets[GD_MEMBER], UserToolWnd, 0l,
  410.                           GTMX_Active, 2, TAG_DONE );
  411.         return;
  412.     }
  413.  
  414.     switch( Selection ) {
  415.     case 0:
  416.         RemoveGroupFromUser( CurUser->us_UserID, CurGroup->gs_GID );
  417.         break;
  418.     case 1:
  419.         AddGroupToUser( CurUser->us_UserID, CurGroup->gs_GID );
  420.         break;
  421.     case 2:
  422.         Tags[7] = ( LONG )"Group File Information";
  423.         User = UserWithID( CurGroup->gs_MgrID );
  424.         if( rtEZRequest( "%s is currently manager of that group.\n"
  425.                         "Make %s the new manager?", "_Ok|_Cancel", 0L,
  426.                         ( struct TagItem * )Tags, User ? User->us_UserName :
  427.                         ( UBYTE * )"<error>", CurUser->us_UserName )) {
  428.             CurGroup->gs_MgrID = CurUser->us_UserID;
  429.         } else {
  430.             UpdateMember();
  431.             return;
  432.         }
  433.         break;
  434.     }
  435.     GroupFileDirty = 1;
  436. }
  437.  
  438. int MEMBERClicked( void )
  439. {
  440.     DoMEMBER( UserToolMsg.Code );
  441.  
  442.     return 1;
  443. }
  444.  
  445. int UserToolSAVE( void )
  446. {
  447.     if(!( PasswdFileDirty || GroupFileDirty )) {
  448.         Tags[7] = ( LONG )"UserTool Information";
  449.         rtEZRequest( "There are no changes to be saved.", "_Ok", 0L,
  450.                     ( struct TagItem * )Tags );
  451.     }
  452.     
  453.     if( PasswdFileDirty ) {
  454.         WritePasswdFile( 0L );
  455.         PasswdFileDirty = 0;
  456.     }
  457.  
  458.     if( GroupFileDirty ) {
  459.         WriteGroupFile();
  460.         GroupFileDirty = 0;
  461.     }
  462.  
  463.     return 1;
  464. }
  465.  
  466. int UserToolABOUT( void )
  467. {
  468.     Tags[7] = ( LONG )"UserTool Information";
  469.     rtEZRequest( VERS" ("DATE")\nby Michael D. Bayne\n\nbaynemd@nextwork."
  470.                 "rose-hulman.edu", "_Ok", 0L, ( struct TagItem * )Tags );
  471.     
  472.     return 1;
  473. }
  474.  
  475. int UserToolQUIT( void )
  476. {
  477.     UBYTE *String;
  478.  
  479.     if( PasswdFileDirty || GroupFileDirty ) {
  480.         if( PasswdFileDirty && GroupFileDirty )
  481.             String = "The password and group files have not been saved.\nSave"
  482.                 " them before quitting?";
  483.         else if( PasswdFileDirty )
  484.             String = "The password file has not been saved.\nSave it before"
  485.                 " quitting?";
  486.         else
  487.             String = "The group file has not been saved.\nSave it before"
  488.                 " quitting?";
  489.         Tags[7] = ( LONG )"File Request";
  490.         switch( rtEZRequest( String, "_Yes|_No|_Don't Quit", 0L,
  491.                             ( struct TagItem * )Tags )) {
  492.         case 1:
  493.             UserToolSAVE();
  494.             break;
  495.         case 2:
  496.             break;
  497.         case 0:
  498.             return 1;
  499.         default:
  500.             break;
  501.         }
  502.     }
  503.     
  504.     return 0;
  505. }
  506.  
  507. int UserToolCloseWindow( void )
  508. {
  509.     return UserToolQUIT();
  510. }
  511.  
  512. int UserToolVanillaKey( void )
  513. {
  514.     LONG Selection;
  515.  
  516.     switch( UserToolMsg.Code ) {
  517.     case 'U':    
  518.         if( CurUser->us_Node.ln_Pred != ( struct Node * )Users ) {
  519.             Selection = NodePos( Users, ( struct Node * )CurUser );
  520.             GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  521.                               GTLV_Selected, Selection - 1, TAG_DONE );
  522.             UpdateGadgets( Selection - 1 );
  523.         }
  524.         break;
  525.     case 'u':
  526.         if( CurUser->us_Node.ln_Succ != ( struct Node * )&Users->lh_Tail ) {
  527.             Selection = NodePos( Users, ( struct Node * )CurUser );
  528.             GT_SetGadgetAttrs( UserToolGadgets[GD_USERS], UserToolWnd, 0l,
  529.                               GTLV_Selected, Selection + 1, TAG_DONE );
  530.             UpdateGadgets( Selection + 1 );
  531.         }
  532.         break;
  533.     case 'n':
  534.         return NEWClicked();
  535.     case 'd':
  536.         return DELETEClicked();
  537.     case '\t':
  538.     case 'i':
  539.         ActivateGadget( UserToolGadgets[GD_USERID], UserToolWnd, 0L );
  540.         break;
  541.     case 'h':
  542.         ActivateGadget( UserToolGadgets[GD_HOMEDIR], UserToolWnd, 0L );
  543.         break;
  544.     case 'r':
  545.         ActivateGadget( UserToolGadgets[GD_REALNAME], UserToolWnd, 0L );
  546.         break;
  547.     case 'p':
  548.         ActivateGadget( UserToolGadgets[GD_PORT], UserToolWnd, 0L );
  549.         break;
  550.     case 'c':
  551.         return CHANGEPASSClicked();
  552.     case 'G':
  553.         if( CurGroup->gs_Node.ln_Pred != ( struct Node * )Groups ) {
  554.             Selection = NodePos( Groups, ( struct Node * )CurGroup );
  555.             GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  556.                               GTLV_Selected, Selection - 1, TAG_DONE );
  557.             UpdateGroups( Selection - 1 );
  558.         }
  559.         break;
  560.     case 'g':
  561.         if( CurGroup->gs_Node.ln_Succ != ( struct Node * )&Groups->lh_Tail ) {
  562.             Selection = NodePos( Groups, ( struct Node * )CurGroup );
  563.             GT_SetGadgetAttrs( UserToolGadgets[GD_GROUPS], UserToolWnd, 0l,
  564.                               GTLV_Selected, Selection + 1, TAG_DONE );
  565.             UpdateGroups( Selection + 1 );
  566.         }
  567.         break;
  568.     case 'o':
  569.         GT_SetGadgetAttrs( UserToolGadgets[GD_MEMBER], UserToolWnd, 0l,
  570.                           GTMX_Active, 0, TAG_DONE );
  571.         DoMEMBER( 0 );
  572.         break;
  573.     case 'm':
  574.         GT_SetGadgetAttrs( UserToolGadgets[GD_MEMBER], UserToolWnd, 0l,
  575.                           GTMX_Active, 1, TAG_DONE );
  576.         DoMEMBER( 1 );
  577.         break;
  578.     case 'a':
  579.         GT_SetGadgetAttrs( UserToolGadgets[GD_MEMBER], UserToolWnd, 0l,
  580.                           GTMX_Active, 2, TAG_DONE );
  581.         DoMEMBER( 2 );
  582.         break;
  583.     case 'e':
  584.         NEWGROUPClicked();
  585.         break;
  586.     case 'l':
  587.         DELETEGROUPClicked();
  588.     default:
  589.         break;
  590.     }
  591.  
  592.     return 1;
  593. }
  594.